home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- ** helpwin.c: Display a little help window of a character **
- ** Écrit par T.Pierron **
- ** 15-03-1999 **
- ***********************************************************/
-
- #include <intuition/intuition.h>
- #include <graphics/rastport.h>
- #include <graphics/text.h>
- #include <exec/memory.h>
- #include <devices/keymap.h>
-
- #include "cmap.h"
- #define CATCOMP_NUMBERS
- #define CATCOMP_STRINGS
- #include "cmap_strings.h"
-
- extern struct RastPort *RP,RPT;
- extern struct Screen *screen;
-
- /*** Measure the maximal lenght of a NULL-terminated array of string: ***/
- WORD Meas_table(UBYTE **strings)
- {
- register UBYTE **p;
- register WORD maxlen,len;
-
- for(p=strings, maxlen=0; *p; p++)
- if(maxlen < (len=TextLength(&RPT,*p,strlen(*p)))) maxlen = len;
-
- return maxlen;
- }
-
- TEXT *Qualifier[]={ "ctrl ","shift ","alt " },Str[50];
-
- /*** Put description of keystroke for character into buffer ****
- **** Original source code taken from FontViewQ by Dieter Temme ****
- **** Tanks for its great work! Code remains almost unchanged ***/
- void GoodMapANSI(UBYTE chr, TEXT *buffer)
- {
- /* >> these definitions are hopefully ok in all national keymaps! << */
- #define NUMDEADKEYS 5 /* a maximum of 16 is possible */
- static TEXT deadkeys[NUMDEADKEYS]= /* rawkey codes of deadkeys */
- { 0x23, 0x24, 0x25, 0x26, 0x27 };
-
- struct KeyMap *km=(void *) AskKeyMapDefault(); /* pointer to default keymap */
- UBYTE qualflags; /* qualifiers SHIFT, ALT, CTRL */
- UBYTE key; /* raw key number 0x00 .. 0x7f */
- UBYTE dead= 0; /* number of deadkey from table */
-
- static const UBYTE mapoffsets[8][8] = /* [LoKeyMapTypes[lokey]][qualflags] */
- { /* none, S, A, SA, C, SC, AC, SAC */
- { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, /* none */
- { 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, /* S */
- { 0x00, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff }, /* A */
- { 0x00, 0x01, 0x02, 0x03, 0xff, 0xff, 0xff, 0xff }, /* SA */
- { 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff }, /* C */
- { 0x00, 0x01, 0xff, 0xff, 0x02, 0x03, 0xff, 0xff }, /* S C */
- { 0x00, 0xff, 0x01, 0xff, 0x02, 0xff, 0x03, 0xff }, /* AC */
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 } /* SAC */
- };
-
- buffer[0]= '\0';
-
- /*- get control characters using the common way -*/
- if ((chr&0x7f) < ' ')
- { union
- { UWORD word;
- struct
- { UBYTE code, qual;
- } bytes;
- } buf;
-
- if (MapANSI(&chr, 1, &buf, 1, NULL) > 0)
- { key= buf.bytes.code;
- qualflags= 0;
- if (buf.bytes.qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- qualflags|= KCF_SHIFT;
- if (buf.bytes.qual&(IEQUALIFIER_LALT|IEQUALIFIER_RALT))
- qualflags|= KCF_ALT;
- if (buf.bytes.qual&(IEQUALIFIER_CONTROL))
- qualflags|= KCF_CONTROL;
- goto found;
- }
- }
-
- /*- find rawkey qualifier and code in keymap -*/
- { BYTE offset; /* byte offset into LoKeyMap[lokey] */
- BOOL deadflag; /* FALSE: search non-dead, TRUE: dead */
- UBYTE *kmtypes; /* pointer into km_??KeyMapTypes */
- ULONG *kmmap; /* pointer into km_??KeyMap */
-
- /*- sorry, original MapANSI, is a little bit broken, whereas this one works... -*/
- for (deadflag= FALSE; deadflag <= TRUE; deadflag++)
- { for (qualflags= KC_NOQUAL; qualflags <= KC_VANILLA; qualflags++)
- { for (key= 0; key <= 0x78; key++)
- { if (!(key&0x3f))
- { kmtypes= key&0x40?
- km->km_HiKeyMapTypes : km->km_LoKeyMapTypes;
- kmmap= key&0x40? km->km_HiKeyMap: km->km_LoKeyMap;
- }
- offset= mapoffsets[*kmtypes&KC_VANILLA][qualflags];
- if (!(*kmtypes&KCF_NOP) && (offset >= 0))
- { if (*kmtypes&KCF_DEAD)
- { UBYTE *addr= (UBYTE *)*kmmap;
- if (addr[offset<<1]&DPF_MOD)
- { addr+= addr[(offset<<1)|1]+deadflag;
- dead= deadflag;
- do
- { if (*addr == chr) goto found;
- addr++;
- dead++;
- } while (deadflag && (dead != NUMDEADKEYS+1));
- dead= 0;
- } else if (((UWORD *)addr)[offset] == (UWORD)chr)
- goto found;
- } else if (!deadflag && !(offset&4))
- { offset= (offset&3)^3;
- if (*kmtypes&KCF_STRING)
- { UBYTE *addr= (UBYTE *)*kmmap;
- if ((addr[offset<<1] == 1)
- && (addr[addr[(offset<<1)|1]] == chr))
- goto found;
- } else if (((UBYTE *)kmmap)[offset] == chr)
- goto found;
- }
- }
- kmtypes++;
- kmmap++;
- }
- }
- }
- }
- return; /* not found */
-
- found:
- /*- put description into buffer -*/
- { struct InputEvent ie; /* structure for MapRawKey() */
- TEXT *index; /* temporary index for highkeys */
-
- static UBYTE highkeycodes[]=
- { 0x40, 0x48, 0x50, 0x58,
- 0x41, 0x49, 0x51, 0x59,
- 0x42, 0x52, 0x5f,
- 0x43, 0x4b, 0x53,
- 0x44, 0x4c, 0x54, 0x6e,
- 0x45, 0x4d, 0x55, 0x6f,
- 0x46, 0x4e, 0x56, 0x70,
- 0x47, 0x4f, 0x57, 0x71, 0
- };
- /*- corresponding key names of previous rawkey codes -*/
- static TEXT *highkeytexts[]=
- { "space", "page up", "f1", "f9",
- "backspace", "page down", "f2", "f10",
- "tab", "f3", "help",
- "enter", "f11", "f4",
- "return", "up", "f5", "pause",
- "esc", "down", "f6", "f12",
- "del", "right", "f7", "home",
- "insert", "left", "f8", "end"
- };
- static TEXT numkeycodes[]=
- { 0x0f, 0x1d, 0x1e, 0x1f, 0x2d, 0x2e, 0x2f, 0x3c,
- 0x3d, 0x3e, 0x3f, 0x4a, 0x5a, 0x5b, 0x5c, 0x5d,
- 0x5e, 0
- };
-
- ie.ie_Class= IECLASS_RAWKEY;
- ie.ie_Qualifier= 0;
- ie.ie_EventAddress= 0;
-
- /*- dead key need to be pushed before -*/
- if (dead)
- { strcpy(buffer, "alt , ");
- ie.ie_Code=deadkeys[dead-1];
- MapRawKey(&ie, buffer+4, 1, km);
- }
-
- if (qualflags&KCF_CONTROL) strcat(buffer, Qualifier[0]);
- if (qualflags&KCF_SHIFT) strcat(buffer, Qualifier[1]);
- if (qualflags&KCF_ALT) strcat(buffer, Qualifier[2]);
-
- if (key && (index = (TEXT *) strchr(highkeycodes, key)))
- strcat(buffer, highkeytexts[index-highkeycodes]);
- else
- { if (key && strchr(numkeycodes, key)) strcat(buffer, "nk ");
- strcat(buffer," "); ie.ie_Code= key;
- MapRawKey(&ie, strrchr(buffer, ' '), 1, km);
- }
- }
- }
-
-
- #define NBPOPMSG (sizeof(popmsg)/sizeof(popmsg[0])-1)
-
- extern UBYTE MaxWid;
- extern WORD txtpen,poppen,shine,darkpen;
- UBYTE *popmsg[]={ MSG_CODE_STR,MSG_DEC_STR,MSG_HEX_STR,MSG_OCT_STR,0 },Digits[]="0999";
- WORD Xp[NBPOPMSG+1], Yp, DgtW, MaxX, MaxY, MaxMsg;
-
- /*** Init width and height of our help window: ***/
- void Init_helpwin( struct Window *Wnd )
- {
- UBYTE I, **msg;
- SetFont(&RPT, screen->RastPort.Font);
- SetFont(RP = Wnd->RPort, RPT.Font);
-
- /** Compute some text width **/
- MaxX = Wnd->Width-Wnd->BorderRight-1;
- MaxY = Wnd->Height-Wnd->BorderBottom-1;
- DgtW = TextLength(&RPT,Digits,sizeof(Digits)-1)+5;
- Yp = MaxY-RPT.Font->tf_YSize;
- for(MaxMsg=1, msg=popmsg, Xp[0]=10; MaxMsg <= NBPOPMSG; MaxMsg++, msg++)
- /* Be sure keystroke can be entirely visible */
- if( (Xp[ MaxMsg ] = TextLength(&RPT,*msg,strlen(*msg)) + Xp[MaxMsg-1] + (MaxMsg==1 ? MaxWid : DgtW) + 5) > MaxX-120 )
- break;
- MaxMsg--;
-
- /** Draws shape of information box **/
- SetAPen(RP,darkpen);
- Move(RP, Wnd->BorderLeft, Yp-5);
- Draw(RP, MaxX, RP->cp_y);
- SetAPen(RP,shine);
- Move(RP, RP->cp_x, RP->cp_y+1);
- Draw(RP, Wnd->BorderLeft, RP->cp_y);
- SetAPen(RP,poppen);
- RectFill(RP, RP->cp_x, RP->cp_y+1, MaxX, MaxY);
-
- /** Draws some text **/
- SetAPen(RP,shine); SetDrMd(RP,JAM1); Yp += RPT.Font->tf_Baseline;
- for(I=0,msg=popmsg; I<MaxMsg; I++,msg++)
- Move(RP,Xp[I],Yp),Text(RP,*msg,strlen(*msg));
-
- /** Vertical rule **/
- SetAPen(RP,darkpen);
- Move(RP, Xp[I], MaxY);
- Draw(RP, RP->cp_x, Yp-RPT.Font->tf_Baseline-5);
- SetAPen(RP,shine);
- Move(RP, RP->cp_x+1, RP->cp_y+1);
- Draw(RP, RP->cp_x, MaxY);
- }
-
- /*** Convert bin to Base ***/
- void convert_to_base(UBYTE *Str,UBYTE Var,BYTE Base)
- {
- UBYTE ChConv[]="0123456789abcdef";
- UBYTE *ptr=Str,L=0;
-
- do {
- L++;
- *ptr-- = ChConv[ Var%Base ];
- } while(Var /= Base);
-
- switch( Base )
- {
- case 16: *ptr--='x'; L++;
- case 8: *ptr--='0'; L++;
- }
- Text(RP,ptr+1,L);
- }
-
- /*** Display information in the window: ***/
- void Disp_charinfo( UBYTE Num )
- {
- struct TextFont *Old;
- int i, CharLen;
-
- Old = RP->Font;
- SetFont(RP,screen->RastPort.Font);
- SetAPen(RP,poppen); SetBPen(RP,poppen); SetDrMd(RP,JAM2);
- /* Code of character (maybe larger than believed) */
- CharLen = TextLength(RP,&Num,1);
- RectFill(RP, Xp[1]-MaxWid-2, Yp-RP->Font->tf_Baseline, Xp[1]-1, MaxY);
- if(CharLen <= MaxWid)
- SetAPen(RP, shine), Move(RP,Xp[1]-2-(MaxWid+CharLen>>1),Yp), Text(RP,&Num,1);
-
- for(i=2; i<=MaxMsg; i++)
- {
- /* Clears old text before */
- SetAPen(RP,shine);
- Move(RP,Xp[i] - DgtW,Yp);
- convert_to_base(Str+6,Num,i==2? 10 : i==3? 16 : 8);
-
- SetAPen(RP,poppen);
- RectFill(RP, RP->cp_x, RP->cp_y - RP->Font->tf_Baseline, Xp[i]-1, MaxY);
- }
- /* Display the keystroke of this char */
- GoodMapANSI(Num, Str);
- Move(RP,Xp[MaxMsg]+7,Yp);
- SetAPen(RP,poppen); SetDrMd(RP,JAM1);
- RectFill(RP,RP->cp_x-4,RP->cp_y-RP->Font->tf_Baseline,MaxX,MaxY);
- SetAPen(RP,shine);
- if( *Str ) Text(RP,Str,strlen(Str));
- if( *Str == 0 )
- {
- /* Keystroke hasn't been found, print msg in italic to **
- ** enlighten that it is not a keystroke sequence */
- RP->AlgoStyle = FSF_ITALIC; SetAPen(RP,shine);
- Text(RP,ErrMsg(MSG_KSNOTFOUND),strlen(ErrMsg(MSG_KSNOTFOUND)));
- RP->AlgoStyle = FS_NORMAL;
- }
- SetFont(RP,Old);
- }
-